﻿using System;
using CSScriptLibrary;
using RaytracerLib.MathLib;
using TomanuExtensions;
using YAXLib;
using RaytracerLib.Script;

namespace RaytracerLib.Layers
{
    public class ProceduralLayer : Layer
    {
        private string m_script;
        private LayerScript m_compiled_script;

        public static readonly string Using = "using RaytracerLib; \n" +
                                              "using RaytracerLib.Layers; \n" +
                                              "using RaytracerLib.MathLib; \n" +
                                              "using RaytracerLib.Script; \n\n";

        public ProceduralLayer(string a_source)
        {
            Script = a_source;
        }

        [YAXNode(CDATA = true)]
        public string Script
        {
            get
            {
                return ScriptUtils.Wrap(m_script);
            }
            set
            {
                m_script = ScriptUtils.Unwrap(value);

                string paramss = null;
                if (m_compiled_script != null)
                    paramss = YAXSerializer.SerializeToString(Params);

                m_compiled_script = (LayerScript)CSScript.LoadCode(
                    Using + Script).CreateObject("*");

                if (paramss != null)
                {
                    m_compiled_script.Params.Inject(
                        YAXSerializer.DeserializeFromString<ScriptParams>(paramss));
                }
            }
        }

        [YAXNode]
        public ScriptParams Params
        {
            get
            {
                return m_compiled_script.Params;
            }
            set
            {
                m_compiled_script.Params.Inject(value);
            }
        }

        public override ColorFloat GetColor(Vector2 a_uv, Intersection a_intersection)
        {
            return m_compiled_script.GetColor(a_uv, a_intersection);
        }

        public override double GetValue(Vector2 a_uv, Intersection a_intersection)
        {
            return m_compiled_script.GetValue(a_uv, a_intersection);
        }

        public override Tangents GetTangents(Vector2 a_uv, Vector2 a_tx, Vector2 a_ty,
            Intersection a_intersection)
        {
            return m_compiled_script.GetTangents(a_uv, a_tx, a_ty, a_intersection);
        }

        public override void RenderStart(RenderStartPhase a_phase)
        {
            m_compiled_script.RenderStart(a_phase);

            base.RenderStart(a_phase);
        }
    }
}